package com.lj.back.manage.scaffold.module.kaptcha.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.common.collect.Maps;
import com.lj.back.manage.scaffold.common.enums.ResponseEnum;
import com.lj.back.manage.scaffold.module.job.annotation.QuartzTask;
import com.lj.back.manage.scaffold.module.kaptcha.service.KaptchaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Priority;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.concurrent.ConcurrentMap;

/**
 * 图形验证码map存储实现类 优先使用本类作为验证码实现类
 * @author lv
 * @version 1.0.0
 */
@Service
@Priority(0)
@Slf4j
public class MapKaptchaServiceImpl implements KaptchaService {

    /**
     * key-value容器  存放验证码
     */
    private static ConcurrentMap<String,String> codes = Maps.newConcurrentMap();

    /**
     * key-expire容器  存放过期时间
     */
    private static ConcurrentMap<String, LocalDateTime> keys = Maps.newConcurrentMap();

    @Override
    public boolean record(String key, String code, long expireTime) {
        //清除无效验证码
        deleteInvalidCode();
        if (keys.containsKey(key) || codes.containsKey(key)){
            return false;
        }
        keys.put(key,LocalDateTime.now().plusSeconds(expireTime));
        codes.put(key,code);
        return true;
    }

    @Override
    public ResponseEnum valid(String key, String code) {
        //清除无效验证码
        deleteInvalidCode();
        LocalDateTime expireTime = keys.get(key);
        String codeByMap = codes.get(key);
        //删除key
        delete(key);
        if (StringUtils.isBlank(codeByMap) || expireTime == null){
            return ResponseEnum.CODE_GRAPH_NOT_FOUND;
        }
        if (LocalDateTime.now().isAfter(expireTime)){
            return ResponseEnum.CODE_GRAPH_INVALID;
        }
        if (!Objects.equals(code.toLowerCase(),codeByMap.toLowerCase())){
            return ResponseEnum.CODE_GRAPH_ERROR;
        }
        return ResponseEnum.SUCCESS;
    }

    @Override
    public boolean delete(String key) {
        //清除无效验证码
        deleteInvalidCode();
        keys.remove(key);
        codes.remove(key);
        return true;
    }

    @Override
    public String getCode(String key) {
        return codes.get(key);
    }

    /**
     * 删除已过期的key  从0分开始每10分钟清除一次无效缓存
     */
    @QuartzTask(id=1,cron = "0 0/10 * * * ? *",name = "定时清除内存中无效验证码")
    public void deleteInvalidCode(){
        keys.forEach((key,expireTime)->{
            if (LocalDateTime.now().isAfter(expireTime)){
                log.info("清除无效验证码：{}",key);
                codes.remove(key);
                keys.remove(key);
            }
        });
    }
}
